package com.bojiu.lawsearch.lawsearch.service.impl;

import com.bojiu.lawsearch.lawsearch.mapper.*;
import com.bojiu.lawsearch.lawsearch.model.*;
import com.bojiu.lawsearch.lawsearch.service.SearchService;
import com.bojiu.lawsearch.lawsearch.util.Constances;
import com.bojiu.lawsearch.lawsearch.util.JsonResult;
import com.bojiu.lawsearch.lawsearch.util.ResultCode;
import com.bojiu.lawsearch.lawsearch.util.UtilTools;
import io.netty.util.NetUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.beans.Transient;
import java.util.*;

/**
 * @author: afdiao
 * @Date：2020/3/18 16:37
 * @Description:
 */
@Service
@Slf4j
public class SearchServiceImpl implements SearchService {

    @Autowired
    LawBaseInfoMapper lawBaseInfoMapper;

    @Autowired
    RuleLabelMapper ruleLabelMapper;

    @Autowired
    SearchQuestionMapper searchQuestionMapper;

    @Autowired
    RuleMapper ruleMapper;

    @Autowired
    UserCollectMapper userCollectMapper;

    @Autowired
    ProfessionMapper professionMapper;

    @Override
    public List<LawBaseInfo> search(SearchFactor searchFactor) throws Exception {
        if (StringUtils.isEmpty(searchFactor.getRule().trim())) {
            log.error("search rule is null");
            return null;
        }

        //优先保存问题
        if (!StringUtils.isEmpty(searchFactor.getQuestion())) {
            if (searchQuestionMapper.selectCountByExample(UtilTools.createExampleByKey("content", searchFactor.getQuestion(), SearchQuestion.class)) == 0) {
                SearchQuestion searchQuestion = new SearchQuestion();
                searchQuestion.setContent(searchFactor.getQuestion());
                searchQuestionMapper.insertSelective(searchQuestion);
            }
        }

        //分隔行业
        if (!StringUtils.isEmpty(searchFactor.getProfession_ids())) {
            String newIds = searchFactor.getProfession_ids();
            searchFactor.setProfession_ids(newIds);
            String sql = UtilTools.changeStrForSql(searchFactor.getProfession_ids());
            searchFactor.setProfession_ids(sql);
        }
        List<LawBaseInfo> lawBaseInfos = new ArrayList<>();
        if (searchFactor.getTitleId() != null) {
            if (lawBaseInfoMapper.selectCountByExample(UtilTools.createExampleByKey("id", searchFactor.getTitleId(), LawBaseInfo.class)) != 0) {
                LawBaseInfo lawBaseInfo = (LawBaseInfo) lawBaseInfoMapper.selectOneByExample(UtilTools.createExampleByKey("id", searchFactor.getTitleId(), LawBaseInfo.class));
                lawBaseInfos.add(lawBaseInfo);
            }
        } else {
            lawBaseInfos = lawBaseInfoMapper.searchBaseInfoByFactor(searchFactor);
        }
        //先查询相关联的大标题内容
        log.debug("lawBase is :{}", lawBaseInfos);

        if (lawBaseInfos.isEmpty()) {
            log.debug("本次查询大标题为空");
            return null;
        }

        //在更具大标题id查询相关联的条例
        StringBuffer stringBuffer = new StringBuffer();
        Map<Integer, LawBaseInfo> idToInfo = new HashMap<>();
        for (LawBaseInfo lawBaseInfo : lawBaseInfos) {
            stringBuffer.append("'").append(lawBaseInfo.getId()).append("',");
            idToInfo.put(lawBaseInfo.getId(), lawBaseInfo);
        }
        String substring = stringBuffer.substring(0, stringBuffer.length() - 1);
        String titleIds = "(" + substring + ")";
        searchFactor.setTitleIds(titleIds);

        //----------------------开始处理检错对象-------------------
        Set<String> ruleSet = new HashSet<>();
        for (String string : searchFactor.getRule().split(" ")) {
            if (!StringUtils.isEmpty(string)) {
                ruleSet.add(string);
            }
        }
        StringBuffer ruleStringBuffer = new StringBuffer();
        for (String string : ruleSet) {
            ruleStringBuffer.append(" and body like '%").append(string).append("%'");
        }

        //检索对象跟单位一起查询
        List<Integer> ruleIdByBodyAndUnit = ruleMapper.getRuleIdByBodyAndUnit(ruleStringBuffer.toString(), searchFactor.getUnitName());
        if (ruleIdByBodyAndUnit.isEmpty()) {
            log.debug("检索对象以及单位查询为空");
            return null;
        }

        String Aids = UtilTools.changeListForSql(ruleIdByBodyAndUnit);

//        //A类
//        log.debug("start a ===========================");
//        List<Integer> ruleIdByBody = new ArrayList<>();
//        if (!StringUtils.isEmpty(searchFactor.getRule())) {
//            log.debug("rule is :{}", searchFactor.getRule());
//            ruleIdByBody = ruleMapper.getRuleIdByBody(searchFactor.getRule());
//        }
//        String Aids = UtilTools.changeListForSql(ruleIdByBody);
//        log.debug("aid is :{}", Aids);
//        searchFactor.setAids(Aids);
//
//        log.debug("start b ===========================");
//        //B类 问题描述
//        List<Integer> describeList = new ArrayList<>();
//        if (!StringUtils.isEmpty(searchFactor.getRuleDescribe())) {
//            log.debug("RuleDescribe is :{}", searchFactor.getRuleDescribe());
//            describeList = ruleMapper.getRuleIdByBody(searchFactor.getRuleDescribe());
//        }
//        Set<Integer> describeSet = getRuleIdsByMessage(searchFactor.getRuleDescribe());
//        describeSet.addAll(describeList);
//        //B类计量单位
//        List<Integer> unitList = new ArrayList<>();
//        if (!StringUtils.isEmpty(searchFactor.getUnitName())) {
//            unitList = ruleMapper.getRuleIdByBody(searchFactor.getUnitName());
//        }
//        Set<Integer> unitSet = getRuleIdsByMessage(searchFactor.getUnitName());
//        unitSet.addAll(unitList);
//        //B类所有
//        List<Integer> BidList = new ArrayList<>();
//        if (!unitSet.isEmpty() || !describeSet.isEmpty()) {
//            BidList = ruleMapper.getRuleIdBy2SetIds(UtilTools.changeSetForSql(unitSet), UtilTools.changeSetForSql(describeSet));
//        }
//        String Bids = UtilTools.changeListForSql(BidList);
//        searchFactor.setBids(Bids);
//        log.debug("Bids is :{}", Bids);

        //c类
        log.debug("start c ===========================");
        //获取题目关联
//        List<Integer> questionList = new ArrayList<>();
//        if (!StringUtils.isEmpty(searchFactor.getQuestion())) {
//            log.debug("Question is :{}", searchFactor.getQuestion());
//            questionList = ruleMapper.getRuleIdByBody(searchFactor.getQuestion());
//        }
        String Cids = null;
        if (!StringUtils.isEmpty(searchFactor.getQuestion())) {
            Set<Integer> questionSet = getRuleIdsByMessage(searchFactor.getQuestion());
            if (questionSet.isEmpty()) {
                log.error("cid is null");
                return null;
            }
            Cids = UtilTools.changeSetForSql(questionSet);
            searchFactor.setCids(Cids);
            log.debug("Cids is :{}", Cids);
        }


//        log.debug("start d ===========================");
//        List<Integer> labelList = new ArrayList<>();
//        if (!(Aids == null && Bids == null && Cids == null)) {
//            if (!StringUtils.isEmpty(searchFactor.getLabelIds())) {
//                labelList = ruleLabelMapper.getRuleIdsByLabelIds(UtilTools.changeStrForSql(searchFactor.getLabelIds()));
//            }
//        }
//        String Dids = UtilTools.changeListForSql(labelList);
//        searchFactor.setDids(Dids);
//        log.debug("Dids is :{}", Dids);

        //开始判断类型
//        /**
//         *  根据条件设置状态值
//         *  1  A
//         *  2  B
//         *  3  C
//         *  4  AB
//         *  5  AC
//         *  6  BC
//         *  7  ABC
//         */
//        if (Aids != null && Bids == null && Cids == null) {
//            searchFactor.setType(1);
//        } else if (Aids == null && Bids != null && Cids == null) {
//            searchFactor.setType(2);
//        } else if (Aids == null && Bids == null && Cids != null) {
//            searchFactor.setType(3);
//        } else if (Aids != null && Bids != null && Cids == null) {
//            searchFactor.setType(4);
//        } else if (Aids != null && Bids == null && Cids != null) {
//            searchFactor.setType(5);
//        } else if (Aids == null && Bids != null && Cids != null) {
//            searchFactor.setType(6);
//        } else if (Aids != null && Bids != null && Cids != null) {
//            searchFactor.setType(7);
//        } else {
//            log.error("fuck,A is :{},B is :{},C is :{}", Aids, Bids, Cids);
//            searchFactor.setType(8);
//        }
//        log.debug("type is :{}", searchFactor.getType());
//        List<Rule> ruleBySearchFactor = ruleMapper.getRuleBySearchFactor(searchFactor);
        List<Rule> ruleBySearchFactor = ruleMapper.getFinalSearch(Aids, Cids, searchFactor.getTitleIds());
        //讲查询到的条例绑定到大标题下
        Map<Integer, List<Rule>> idToRules = new HashMap<>();
        for (Rule sonRule : ruleBySearchFactor) {
            Integer titleId = sonRule.getTitleId();
            if (idToRules.containsKey(titleId)) {
                idToRules.get(titleId).add(sonRule);
            } else {
                List<Rule> rules = new ArrayList<>();
                rules.add(sonRule);
                idToRules.put(titleId, rules);
            }
        }
        List<LawBaseInfo> result = new ArrayList<>();
        for (Integer titleId : idToRules.keySet()) {
            if (!idToInfo.containsKey(titleId)) {
                continue;
            }
            LawBaseInfo lawBaseInfo = idToInfo.get(titleId);
            List<Rule> rules = idToRules.get(titleId);
            lawBaseInfo.setRules(rules);
            result.add(lawBaseInfo);
        }
        if (searchFactor.getTitleId() != null) {
            return result;
        }
        //下面开始排序
        List<LawBaseInfo> finalResult = sortLawBaseInfo(result);
        return finalResult;
    }

    /**
     * 根据文字匹配标签从而关联ruleid
     *
     * @param message
     * @return
     */
    private Set<Integer> getRuleIdsByMessage(String message) {
        Set<Integer> idSet = new HashSet<>();
        if (StringUtils.isEmpty(message)) {
            return idSet;
        }
        List<RuleLabel> ruleLabels = ruleLabelMapper.selectAll();
        for (RuleLabel ruleLabel : ruleLabels) {
            if (message.contains(ruleLabel.getLabel())) {
                idSet.add(ruleLabel.getRules_id());
            }
        }
        return idSet;
    }


    /**
     * 根据比重计算各个总得分
     *
     * @param lawBaseInfos
     */
    private void countScore(List<LawBaseInfo> lawBaseInfos) {
        double score = 0.0;
        for (LawBaseInfo lawBaseInfo : lawBaseInfos) {
            //设置行业中文名
            if (lawBaseInfo.getProfession_id() != null) {
                Profession profession = (Profession) professionMapper.selectOneByExample(UtilTools.createExampleByKey("id", lawBaseInfo.getProfession_id(), Profession.class));
                lawBaseInfo.setProfessionName(profession.getName());
            }
            lawBaseInfo.setRelationNum(lawBaseInfo.getRules().size());
            //按照匹配条例数排名
            score = lawBaseInfo.getRules().size() * 0.4;
            //按照条例的收藏数
            for (Rule rule : lawBaseInfo.getRules()) {
                int collect = rule.getCollectCount() == null ? 0 : rule.getCollectCount();
                score = score + collect * 0.15;
            }
            //按照点击量排序
//            score = score + lawBaseInfo.getClickCount() * 0.1;
            lawBaseInfo.setScore(score);
            lawBaseInfo.setRules(null);
        }
    }

    /**
     * 先计算得分
     * 根据计算的得分排名
     *
     * @param lawBaseInfos
     * @return
     */
    private List<LawBaseInfo> sortLawBaseInfo(List<LawBaseInfo> lawBaseInfos) {
        countScore(lawBaseInfos);
        Comparator<LawBaseInfo> lawBaseInfoComparator = new Comparator<LawBaseInfo>() {
            @Override
            public int compare(LawBaseInfo first, LawBaseInfo second) {
                if (first.getScore() - second.getScore() == 0) {
                    return first.getId() - second.getId();
                } else {
                    return second.getScore() > first.getScore() ? 1 : -1;
                }
            }
        };
        Collections.sort(lawBaseInfos, lawBaseInfoComparator);
        return lawBaseInfos;
    }


    @Override
    public void clickCount(int id) {
        lawBaseInfoMapper.clickCount(id);
    }

    @Transactional
    @Override
    public JsonResult collectLabel(UserCollect userCollect, int userId) {
        Map<String, Object> map = new HashMap<>();
        map.put("user_id", userId);
        map.put("rules_id", userCollect.getRules_id());
        //判断有没有重复收藏
        if (userCollectMapper.selectCountByExample(UtilTools.createExampleByMap(map, UserCollect.class)) > 0) {
            log.error("该条例已经收藏无需重复收藏");
            return new JsonResult(ResultCode.SAME_DATA);
        }
        userCollect.setUser_id(userId);
        userCollectMapper.insertSelective(userCollect);
        //判断标签存不存在，存在的话标签数加一，不存在就加入新的标签
        map.clear();
        map.put("rules_id", userCollect.getRules_id());
        map.put("label", userCollect.getLabel());
        if (ruleLabelMapper.selectCountByExample(UtilTools.createExampleByMap(map, RuleLabel.class)) == 0) {
            //不存在则插入
            List<RuleLabel> ruleLabels = ruleLabelMapper.selectByExample(UtilTools.createExampleByKey("rules_id", userCollect.getRules_id(), RuleLabel.class));
            RuleLabel ruleLabel = ruleLabels.get(0);
            ruleLabel.setLabel(userCollect.getLabel());
            ruleLabel.setId(null);
            ruleLabel.setCount(1);
            ruleLabelMapper.insertSelective(ruleLabel);
        } else {
            //存在则加一
            ruleLabelMapper.addCountByCollect(userCollect.getRules_id(), userCollect.getLabel());
        }
        return new JsonResult(ResultCode.SUCCESS);
    }

    @Override
    public JsonResult getAll(int titleId) {
        LawBaseInfo lawBaseInfo = (LawBaseInfo) lawBaseInfoMapper.selectOneByExample(UtilTools.createExampleByKey("id", titleId, LawBaseInfo.class));
        String filePath = Constances.WEB_URL + lawBaseInfo.getPdfFileName();
        return new JsonResult(ResultCode.SUCCESS, filePath);
    }
}
